﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CCL.Utility;

namespace CCL.SocketMessage.Response
{
    /// <summary>
    /// 프로젝트 리스트 요청에 대한 응답을 제공합니다.
    /// </summary>
    public class GetProjectList : Body, IResponsable
    {
        /// <summary>
        /// 요청 성공여부를 가져옵니다.
        /// </summary>
        public Constant.Result Result { get; private set; }

        /// <summary>
        /// 요청 실패시 ErrorMessage를 가져옵니다.
        /// (요청 성공시에는 null)
        /// </summary>
        public char[] ErrorMessage { get; private set; }

        /// <summary>
        /// 프로젝트 리스트를 가져옵니다.
        /// </summary>
        public List<TableStructure.Project> ProjectList { get; private set; }

        /// <summary>
        /// 직렬화된 byte 배열을 통해 GetProjectList 객체를 생성합니다.
        /// </summary>
        /// <param name="bytes">직렬화된 byte 배열</param>
        public GetProjectList(byte[] bytes)
        {
            int start = 0 ;

            Result = (Constant.Result)bytes[0];
            start += sizeof(byte);

            if (Result == Constant.Result.Fail)
            {
                ErrorMessage = new char[Constant.Length.ErrorMessage];
                Encoding.Default.GetChars(bytes, start, Constant.Length.ErrorMessage, ErrorMessage, 0);

                ProjectList = null;
            }
            else
            {
                ErrorMessage = null;

                ProjectList = new List<TableStructure.Project>();

                int tableSize = TableStructure.Project.TableSize;

                for (; start < bytes.Length; start += tableSize)
                {
                    byte[] tableBytes = new byte[tableSize];

                    Array.Copy(bytes, start, tableBytes, 0, tableSize);

                    TableStructure.Project projectTable = new TableStructure.Project(tableBytes);

                    ProjectList.Add(projectTable);
                }
            }
        }

        /// <summary>
        /// 성공한 응답 GetProjectList를 생성합니다.
        /// </summary>
        /// <param name="projectList"></param>
        public GetProjectList(List<TableStructure.Project> projectList)
        {
            Result = Constant.Result.Success;
            ErrorMessage = null;
            ProjectList = projectList;
        }

        /// <summary>
        /// 실패한 응답 GetProjectList를 생성합니다.
        /// </summary>
        /// <param name="errorMessage"></param>
        public GetProjectList(string errorMessage)
        {
            Result = Constant.Result.Fail;
            ErrorMessage = StringUtility.StringCopy(errorMessage, Constant.Length.ErrorMessage);
            ProjectList = null;
        }

        /// <summary>
        /// 바이트 배열로 직렬화 합니다.
        /// </summary>
        /// <returns>직렬화된 바이트 배열</returns>
        public override byte[] GetByte()
        {
            byte[] bytes = new byte[GetSize()];

            int start = 0;

            bytes[0] = (byte)Result;
            start += sizeof(byte);

            if (Result == Constant.Result.Success)
            {
                foreach (TableStructure.Project projTable in ProjectList)
                {
                    byte[] tableBytes = projTable.GetByte();

                    Array.Copy(tableBytes, 0, bytes, start, TableStructure.Project.TableSize); 
                    start += tableBytes.Length;
                }
            }
            else
            {
                byte[] temp;

                temp = Encoding.Default.GetBytes(ErrorMessage);
                Array.Copy(temp, 0, bytes, start, Constant.Length.ErrorMessage);
            }

            return bytes;
        }

        /// <summary>
        /// 직렬화 가능한 객체의 바이트 사이즈를 가져옵니다.
        /// </summary>
        /// <returns>직렬화된 바이트 사이즈</returns>
        public override uint GetSize()
        {
            uint size = 0;

            size += sizeof(byte);

            if (Result == Constant.Result.Success)
            {
                size += (uint)(TableStructure.Project.TableSize * ProjectList.Count);
            }
            else
            {
                size += Constant.Length.ErrorMessage;
            }

            return size;
        }
    }
}
